package servlet;

import bean.DealRecord;
import bean.User;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import dao.DealRecordDao;
import dao.UserDao;
import util.*;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * 用于发起支付请求和数据初始入库（insert）
 * url示例（手机）：/goalipay?userid=1&money=2
 * url示例（电脑）：/goalipay?device=desktop&userid=1&money=2
 *
 * @author dsf
 */
@WebServlet(name = "AlipayServlet", urlPatterns = "/goalipay")
public class AlipayServlet extends HttpServlet {

    private DealRecordDao dealRecordDao = new DealRecordDao();
    private UserDao userDao = new UserDao();

    /**
     * 不使用doGet()方法
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ResponseUtil.writeBadRequest(resp);
    }

    /**
     * 发起支付宝支付，并进行数据入库（设定alipayStatus=1）
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        JsonWrapper result = new JsonWrapper();
        if (StringUtil.isNotEmpty(req.getParameter("userid")) && StringUtil.isNotEmpty(req.getParameter("money"))) {
            //从请求获取所需参数
            String device = req.getParameter("device");
            String userId = req.getParameter("userid");
            // 交易类型写死为1（即充值）
            String actionType = "1";
            String money = req.getParameter("money");
            String actionTime = DealRecordUtil.getTimeNow();
            String balance = null;
            User userSearchPara = new User();
            userSearchPara.setUserId(userId);
            List<Object> userSearchRes;
            userSearchRes = userDao.userList(null, userSearchPara);
            if (userSearchRes.size() != 0) {
                User user = (User) userSearchRes.get(0);
                balance = DealRecordUtil.formatBalance(user.getBalance());
            } else {
                System.out.println("get user info failed!");
                result.setStatus(403);
                result.setMsg("failed");
                ResponseUtil.write(resp, result.get());
                System.out.println("Illegal data from front-end!");
                return;
            }

            //设置存库参数
            DealRecord drAddPara = new DealRecord();
            drAddPara.setDealRecordId(DealRecordUtil.getDrId(userId, actionType, actionTime));
            drAddPara.setUserId(userId);
            drAddPara.setActionType(actionType);
            drAddPara.setMoney(money);
            drAddPara.setActionTime(actionTime);
            drAddPara.setCurBalance(DealRecordUtil.getCurBalance(balance, money));
            // 将alipayStatus值写死为1
            drAddPara.setAlipayStatus("1");
            if (DealRecordUtil.dataCheck(drAddPara, balance)) {
                // 获得初始化的AlipayClient
                AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id,
                    AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key,
                    AlipayConfig.sign_type);
                // 设置以下请求参数：
                // 商户订单号，商户网站订单系统中唯一订单号，必填
                String out_trade_no = drAddPara.getDealRecordId();
                // 付款金额，必填
                String total_amount = drAddPara.getMoney();
                // 订单名称，必填
                String subject = "【郑在行】个人余额充值";
                // 商品描述，可空
                String body = "使用郑在行公司的共享单车业务的官方充值账户进行个人余额充值。";
                // 发起电脑网站支付请求
                if (StringUtil.isNotEmpty(device)) {
                    if (device.equals("desktop")) {
                        // 设置请求参数
                        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
                        alipayRequest.setReturnUrl(AlipayConfig.return_url);
                        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

                        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\""
                            + total_amount + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\","
                            + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
                        // 请求
                        String form = "";
                        try {
                            form = alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单
                        } catch (AlipayApiException e) {
                            e.printStackTrace();
                        }
                        // 直接将完整的表单html输出到页面
                        resp.setContentType("text/html;charset=" + AlipayConfig.charset);
                        PrintWriter out = resp.getWriter();
                        out.println("<html>");
                        out.println("<head>");
                        out.println("<title>支付页面</title>");
                        out.println("</head>");
                        out.println("<body>");
                        out.println(form);
                        out.println("</body>");
                        out.println("</html>");
                        out.close();
                    }
                }
                // 发起手机网站支付请求
                else {
                    AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();

                    // 超时时间 可空
                    String timeout_express = "2m";
                    // 销售产品码 必填
                    String product_code = "QUICK_WAP_PAY";

                    // 封装请求支付信息
                    AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
                    model.setOutTradeNo(out_trade_no);
                    model.setSubject(subject);
                    model.setTotalAmount(total_amount);
                    model.setBody(body);
                    model.setTimeoutExpress(timeout_express);
                    model.setProductCode(product_code);
                    alipay_request.setBizModel(model);
                    // 设置异步通知地址
                    alipay_request.setNotifyUrl(AlipayConfig.notify_url);
                    // 设置同步地址
                    alipay_request.setReturnUrl(AlipayConfig.return_url);

                    // form表单生成
                    String form = "";
                    try {
                        // 调用SDK生成表单
                        form = alipayClient.pageExecute(alipay_request).getBody();
                        resp.setContentType("text/html;charset=" + AlipayConfig.charset);
                        // 直接将完整的表单html输出到页面
                        resp.getWriter().write(form);
                        resp.getWriter().flush();
                        resp.getWriter().close();
                    } catch (AlipayApiException e) {
                        e.printStackTrace();
                    }
                }

                try {
                    int drAddRes = dealRecordDao.dealrecordAdd(drAddPara);
                    if (drAddRes != 0) {
                        // 添加成功
                        result.setMsg("success");
                    } else {
                        result.setStatus(403);
                        result.setMsg("failed");
                        ResponseUtil.write(resp, result.get());
                    }
                } catch (Exception e) {
                    // 添加失败
                    result.setStatus(403);
                    result.setMsg("failed");
                    ResponseUtil.write(resp, result.get());
                }
            } else {
                result.setStatus(403);
                result.setMsg("failed");
                ResponseUtil.write(resp, result.get());
                System.out.println("Illegal data from front-end!");
            }
        } else {
            result.setStatus(403);
            result.setMsg("failed");
            ResponseUtil.write(resp, result.get());
            System.out.println("Illegal data from front-end!");
        }
    }
}